/**
 *  功能：SEN0244 gravity TDS Sensor 液体浑浊检测设备
 *  作者：tuut
 *  时间：2023-11-28
 *  描述：
 *      1.设备初始化
 *      2.设备周边温度,读取检测设备在液体中的电阻数值
 *      3.根据电阻数值，计算检测液体浑浊度
 *      4.测试官方方法的使用
*/
#include "Sketch_oct31b_tds.h"  // 功能：SEN0244 gravity TDS 设备引用 液体浑浊检测设备
#include <Arduino.h>
/****************************************SEN0244 part****************************************/
Sketch_oct31b_tds::Sketch_oct31b_tds() {
  Serial.println("Sketch_oct31b_tds Object Created.");
}

Sketch_oct31b_tds::Sketch_oct31b_tds(int sensorPin) {
  Serial.println("Sketch_oct31b_tds Object Created.");
  ONE_WIRE_BUS_PIN = sensorPin;
}

Sketch_oct31b_tds::~Sketch_oct31b_tds() {
  Serial.println("Sketch_oct31b_tds Object Deleted.");
}

int Sketch_oct31b_tds::getPin() {
  return ONE_WIRE_BUS_PIN;
}

String Sketch_oct31b_tds::getTds() {
  return str_tdsNumber;
}

void Sketch_oct31b_tds::setDs18b20Temperature(float currentTemperature) {
  ds18b20Temperature = currentTemperature;
}

/**
 * 功能描述：初始化TDS浑浊探测棒
 */
void Sketch_oct31b_tds::initSEN0244DevManager() {
  cal_delayStart = millis();
  pinMode(ONE_WIRE_BUS_PIN, INPUT);
}

void Sketch_oct31b_tds::loadTDSAPI(long _interval) {
  if ((millis() - cal_delayStart) >= _interval) {
    str_tdsNumber = loadData();
    cal_delayStart = millis();
  }
}

String Sketch_oct31b_tds::loadData() {
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  //every 40 milliseconds,read the analog value from the ADC
  {
    analogSampleTimepoint = millis();
    analogBuffer[analogBufferIndex] = analogRead(ONE_WIRE_BUS_PIN);  //read the analog value and store into the buffer
    analogBufferIndex++;
    if (analogBufferIndex == SCOUNT)
      analogBufferIndex = 0;
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U) {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0;                                                                                                   // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    float compensationCoefficient = 1.0 + 0.02 * (ds18b20Temperature - 25.0);                                                                                                         //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatge = averageVoltage / compensationCoefficient;                                                                                                             //temperature compensation
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5;  //convert voltage value to tds value
    //Serial.print("voltage:");
    //Serial.print(averageVoltage,2);
    //Serial.print("V   ");
    Serial.print("TDS Value:");
    Serial.print(tdsValue, 0);
    Serial.println("ppm");
  }
  return String(tdsValue, 1);
}

int Sketch_oct31b_tds::getMedianNum(int bArray[], int iFilterLen) {
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++)
    bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  return bTemp;
}